package exam;

import utils.TextUtils;

import java.util.*;
import java.sql.Connection;

import question.*;
import setup.SetupInfo;
import setup.Setup;
import setup.KmSetting;
import setup.KmSettingInfo;
import examinee.ExamineeInfo;
import examinee.Examinee;

/**
 * Created by IntelliJ IDEA.
 * User: Shawn
 * Date: 2009-8-23
 * Time: 17:48:04
 */
public class TestPaperGenerator2 {

  private Connection con;
  private long eid;
  private int kmID;

  //key cid
  private Map<Integer, ClassifyInfo> cMap;
  //key ydid
  private Map<Integer, List<QuestionInfo>> qMap;

  private List<SetupInfo> setups;

  public TestPaperGenerator2(Connection con, long eid) throws Exception {
    this.con = con;
    this.eid = eid;

    //get kmID
    ExamineeInfo einfo = Examinee.getExaminee(con, eid);
    kmID = Classify.getKmID(con, einfo.getKskm());
    if (kmID == -1) throw new Exception("no km");

    //classify
    cMap = new HashMap<Integer, ClassifyInfo>();
    List<ClassifyInfo> clist = Classify.getKmList(con, kmID);
    for (ClassifyInfo info : clist) cMap.put(info.getCid(), info);

    //question
    qMap = new HashMap<Integer, List<QuestionInfo>>();
    List<QuestionInfo> questions = Question.getQuestionList(con, kmID);
    for (QuestionInfo question : questions) {
      List<QuestionInfo> list = qMap.get(question.getCid());
      if (list == null) list = new ArrayList<QuestionInfo>();
      list.add(question);
      qMap.put(question.getCid(), list);
    }

    //setup
    setups = Setup.getSetupList(con, kmID);
  }

  public TestPaperInfo generate() throws Exception {
    KmSettingInfo setting = KmSetting.getSetting(con, kmID);
    TestPaperInfo testPaper = new TestPaperInfo(eid, TextUtils.getZeroTime(System.currentTimeMillis()), setting.getExamTime() * 60 * 60 * 1000l, setting.getPassScore(), setting.getSValue(), setting.getMValue(), setting.getTValue());
    long tid = TestPaper.addTestPaper(con, testPaper);
    testPaper.setTid(tid);

    List<AnswerPaperInfo> answerList = getAnswers(tid);
    AnswerPaper.addAnswerPaperList(con, answerList);

    return testPaper;
  }

  private List<AnswerPaperInfo> getAnswers(long tid) throws Exception {
    List<QuestionInfo> slist = new ArrayList<QuestionInfo>();
    List<QuestionInfo> mlist = new ArrayList<QuestionInfo>();
    List<QuestionInfo> tlist = new ArrayList<QuestionInfo>();

    for (SetupInfo setup : setups) {
      List<QuestionInfo> questions = qMap.get(setup.getYdID());
      List<QuestionInfo> result = getQuestions(questions, setup);

      for (QuestionInfo question : result) {
        switch (question.getTx()) {
          case QuestionVar.TX_SINGLE_CHOICE:
            slist.add(question);
            break;
          case QuestionVar.TX_MULTI_CHOICE:
            mlist.add(question);
            break;
          case QuestionVar.TX_TF:
            tlist.add(question);
            break;
        }
      }
    }

    List<AnswerPaperInfo> result = new ArrayList<AnswerPaperInfo>();
    for (QuestionInfo info : tlist) {
      result.add(getAnswerPaperInfo(tid, info));
    }
    for (QuestionInfo info : slist) {
      result.add(getAnswerPaperInfo(tid, info));
    }
    for (QuestionInfo info : mlist) {
      result.add(getAnswerPaperInfo(tid, info));
    }

    return result;
  }

  private List<QuestionInfo> getQuestions(List<QuestionInfo> questions, SetupInfo setupInfo) throws Exception {
    List<QuestionInfo> result = new ArrayList<QuestionInfo>();

    List<QuestionInfo> slist = new ArrayList<QuestionInfo>();
    List<QuestionInfo> mlist = new ArrayList<QuestionInfo>();
    List<QuestionInfo> tlist = new ArrayList<QuestionInfo>();

    for (QuestionInfo question : questions) {
      switch (question.getTx()) {
        case QuestionVar.TX_SINGLE_CHOICE:
          slist.add(question);
          break;
        case QuestionVar.TX_MULTI_CHOICE:
          mlist.add(question);
          break;
        case QuestionVar.TX_TF:
          tlist.add(question);
          break;
      }
    }

    if (setupInfo.getSSum() != 0) {
      result.addAll(getTxQuestions(slist, setupInfo.getSSum()));
    }

    if (setupInfo.getMSum() != 0) {
      result.addAll(getTxQuestions(mlist, setupInfo.getMSum()));
    }

    if (setupInfo.getTSum() != 0) {
      result.addAll(getTxQuestions(tlist, setupInfo.getTSum()));
    }

    return result;
  }

  private List<QuestionInfo> getTxQuestions(List<QuestionInfo> list, int sum) throws Exception {
    if (list.size() < sum) throw new Exception("setup error!");
    List<QuestionInfo> result = new ArrayList<QuestionInfo>();

    while (sum != 0) {
      int index = getRandomIndex(list.size());
      QuestionInfo question = list.get(index);
      list.remove(question);
      result.add(question);
      sum--;
    }

    return result;
  }

  private AnswerPaperInfo getAnswerPaperInfo(long tid, QuestionInfo info) {
    AnswerPaperInfo ainfo = new AnswerPaperInfo(tid, info);
    ClassifyInfo ydInfo = cMap.get(info.getCid());
    ClassifyInfo dtInfo = cMap.get(ydInfo.getParentID());
    ClassifyInfo kmInfo = cMap.get(dtInfo.getParentID());
    ainfo.setYd(ydInfo.getCname());
    ainfo.setDt(dtInfo.getCname());
    ainfo.setKm(kmInfo.getCname());
    return ainfo;
  }

  private int getRandomIndex(int size) {
    return (int) (size * Math.random());
  }
}
